package socket;

import com.sun.xml.internal.ws.handler.ClientLogicalHandlerTube;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

public class Server01 {
    private ServerSocket serverSocket;
    private Map<String, PrintWriter> allOut = new HashMap<>();

    public Server01() {
        try {
            System.out.println("正在启动服务器");
            serverSocket = new ServerSocket(8088);
            System.out.println("服务器启动完毕");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void start() {
        while (true) {
            try {
                System.out.println("等待客户端连接");
                Socket socket = serverSocket.accept();
                System.out.println("一个客户端连接了");
                ClientHandler handle = new ClientHandler(socket);
                Thread t = new Thread();
                t.start();
            } catch (IOException e) {
            }
        }
    }

    public static void main(String[] args) {
        Server01 server01 = new Server01();
        server01.start();
    }

    private class ClientHandler implements Runnable {
        private Socket socket;
        private String host;
        private String nickName;

        public ClientHandler(Socket socket) {
            this.socket = socket;
            host = socket.getInetAddress().getHostAddress();
        }

        PrintWriter pw = null;

        @Override
        public void run() {
            InputStream in = null;
            try {
                in = socket.getInputStream();
                InputStreamReader isr = new InputStreamReader(in, StandardCharsets.UTF_8);
                BufferedReader br = new BufferedReader(isr);

                OutputStream out = socket.getOutputStream();
                OutputStreamWriter ose = new OutputStreamWriter(out);
                BufferedWriter bw = new BufferedWriter(ose);
                pw = new PrintWriter(bw, true);
                nickName = br.readLine();
                synchronized (allOut) {
                    allOut.put(nickName, pw);//将该客户端的输出流加入到集合中
                }
                sendMessageToAll("上线了,当前在线人数:" + allOut.size());
                String message;
                while ((message = br.readLine()) != null) {
                    if (message.startsWith("@")) {
                        sendMessageToSomeone(message);
                    } else {
                        sendMessageToAll("说:" + message);
                    }
                }

            } catch (IOException e) {
            } finally {

                synchronized (allOut) {
                    allOut.remove(nickName);
                }
                sendMessageToAll("下线了,当前在线人数:" + allOut.size());

                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

        }

        private void sendMessageToAll(String message) {
            System.out.println(nickName + "[" + host + "]" + message);
            synchronized (allOut) {

                for (PrintWriter o : allOut.values()) {
                    o.println(nickName + "[" + host + "]" + message);
                }
            }
        }

        private void sendMessageToSomeone(String message) {
            //message的样子:@范传奇：你好
            if (message.matches("@.+:.+")) {//验证私聊格式是否符合
                String toNickName = message.substring(1, message.indexOf(":"));
                if (allOut.containsKey(toNickName)) {
                    PrintWriter pw = allOut.get(toNickName);
                    String toMessage = message.substring(message.indexOf(":") + 1);
                    pw.println(nickName + "悄悄对你说:" + toMessage);
                } else {
                    PrintWriter pw = allOut.get(nickName);
                    pw.println("该用户不在线");
                }
            } else {
                PrintWriter pw = allOut.get(nickName);
                pw.println("私聊格式不正确!");

            }
        }
    }
}